package com.own.component.common.util.encrypt.util;

import com.own.component.common.util.encrypt.BaseEncryptUtil;
import com.own.component.common.util.encrypt.model.CustomEncryptKey;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

/**
 * Aes128Util
 *
 * @author chenxueli
 * @date 2021/3/3 18:15
 */
public class Aes128Util implements BaseEncryptUtil {

    /**
     * 算法名称
     */
    final String KEY_ALGORITHM = "AES";

    /**
     * 加解密算法/模式/填充方式
     */
    final String algorithmStr = "AES/CBC/PKCS7Padding";

    private Key key;
    private Cipher cipher;

    /**
     * 私钥解密
     *
     * @param content          解密内容
     * @param customEncryptKey 秘钥
     * @return 解密后的内容
     */
    @Override
    public String decrypt(String content, CustomEncryptKey customEncryptKey) {
        try {
            var sessionKey = Base64.decodeBase64(customEncryptKey.getSecret());
            var encryptedData = Base64.decodeBase64(content);
            var iv = Base64.decodeBase64(customEncryptKey.getIv());
            init(sessionKey);
            cipher.init(Cipher.DECRYPT_MODE, this.key, new IvParameterSpec(iv));
            return new String(cipher.doFinal(encryptedData), StandardCharsets.UTF_8);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 初始化数据
     *
     * @param keyBytes 内容
     */
    public void init(byte[] keyBytes) {
        // 如果密钥不足16位，那么就补足. 这个if 中的内容很重要
        int base = 16;
        if (keyBytes.length % base != 0) {
            int groups = keyBytes.length / base + 1;
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp, (byte) 0);
            System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length);
            keyBytes = temp;
        }
        // todo 初始化
//        Security.addProvider(new BouncyCastleProvider());
        // 转化成JAVA的密钥格式
        key = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
        try {
            // 初始化cipher
            cipher = Cipher.getInstance(algorithmStr);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }

}
